<?php
/**
 * This file is part of easycrm, created by PhpStorm.
 * Author: LouXin
 * Date: 2015/1/5 13:16
 * File: StatisticModel.php
 */

namespace Icsoc\CustomReportBundle\Model;

use Elasticsearch\Client;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Class StatisticModel
 * @package Icsoc\DataBundle\Model
 */
class AgentStatisticModel
{
    /** 有效通话量指标名称 */
    const VALID_CONN_TOTAL_NUM = 'validConnTotalNum';
    const INBOUND_VALID_CONN_TOTAL_NUM = 'inboundValidConnTotalNum';
    const OUTBOUND_VALID_CONN_TOTAL_NUM = 'outboundValidConnTotalNum';

    private $validItems = array(
        self::VALID_CONN_TOTAL_NUM,
        self::INBOUND_VALID_CONN_TOTAL_NUM,
        self::OUTBOUND_VALID_CONN_TOTAL_NUM,
    );

    /** @var ContainerInterface */
    private $container;

    /** @var Client  */
    private $client;

    /** @var array 呼入数据的统计，包括呼入接通量，呼入通话总时长，呼入通话平均时长 */
    private $inboundConnNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 4)),
                    array('term' => array('ext_type' => 1)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
                'aggs' => array(
                    'inboundConnTotalSecs' => array('sum' => array('field' => 'secs')),
                    'inboundConnAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 外呼通话量 */
    private $outboundTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 9)),
                    array('term' => array('log_type' => 'amount')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
            ),
        ),
    );

    /** @var array 外呼接通量、外呼接通总时长、外呼接通平均时长 */
    private $outboundConnNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 4)),
                    array('term' => array('ext_type' => 2)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
                'aggs' => array(
                    'outboundConnTotalSecs' => array('sum' => array('field' => 'secs')),
                    'outboundConnAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 有效通话量，有效通话总时长，有效通话平均时长 */
    private $validConnTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 4)),
                    array('range' => array('ext_type' => array('from' => 1, 'to' => 2))),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
                'aggs' => array(
                    'validConnTotalSecs' => array('sum' => array('field' => 'secs')),
                    'validConnAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 呼入有效通话量，有效通话总时长，有效通话平均时长 */
    private $inboundValidConnTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 4)),
                    array('term' => array('ext_type' => 1)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
                'aggs' => array(
                    'inboundValidConnTotalSecs' => array('sum' => array('field' => 'secs')),
                    'inboundValidConnAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 呼出有效通话量，有效通话总时长，有效通话平均时长 */
    private $outboundValidConnTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 4)),
                    array('term' => array('ext_type' => 2)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
                'aggs' => array(
                    'outboundValidConnTotalSecs' => array('sum' => array('field' => 'secs')),
                    'outboundValidConnAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 总接通量，通话总时长，通话平均时长 */
    private $connTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 4)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
                'aggs' => array(
                    'connTotalSecs' => array('sum' => array('field' => 'secs')),
                    'connAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 内线通话量，内线通话总时长，内线通话平均时长 */
    private $internalConnNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 4)),
                    array('term' => array('ext_type' => 3)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
                'aggs' => array(
                    'internalConnTotalSecs' => array('sum' => array('field' => 'secs')),
                    'internalConnAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 事后处理量，事后处理总时长，事后处理平均时长 */
    private $waitTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 9)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
                'aggs' => array(
                    'waitTotalSecs' => array('sum' => array('field' => 'secs')),
                    'waitAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 振铃总次数，振铃总时长，振铃平均时长 */
    private $ringTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 2)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
                'aggs' => array(
                    'ringTotalSecs' => array('sum' => array('field' => 'secs')),
                    'ringAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 咨询总次数，咨询总时长，咨询平均时长 */
    private $consultNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 5)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
                'aggs' => array(
                    'consultTotalSecs' => array('sum' => array('field' => 'secs')),
                    'consultAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 保持总次数，保持总时长，保持平均时长 */
    private $holdNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 7)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
                'aggs' => array(
                    'hlodTotalSecs' => array('sum' => array('field' => 'secs')),
                    'holdAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 会议总次数，会议总时长，会议平均时长 */
    private $conferenceNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 6)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
                'aggs' => array(
                    'conferenceTotalSecs' => array('sum' => array('field' => 'secs')),
                    'conferenceAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 转接参与量（包括咨询转接量和被转接量） */
    private $transferTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 8)),
                    array('term' => array('log_type' => 'amount')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
            ),
        ),
    );

    /** @var array 被转接通话量，被转接通话总时长，被转接通话平均时长 */
    private $transferedConnNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 4)),
                    array('term' => array('ext_type' => 4)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
                'aggs' => array(
                    'transferedConnTotalSecs' => array('sum' => array('field' => 'secs')),
                    'transferedConnAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 登录次数、登录总时长 */
    private $loginTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 8)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
                'aggs' => array(
                    'loginTotalSecs' => array('sum' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 就绪总时长 */
    private $readyTotalSecs = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 10)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
                'aggs' => array(
                    'readyTotalSecs' => array('sum' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 示忙总时长 */
    private $busyTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 11)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'ag_groups' => array(
                'terms' => array('field' => 'ag_id', 'size' => 0),
                'aggs' => array(
                    'ext_busy' => array(
                        'terms' => array('field' => 'ext_option', 'size' => 0),
                        'aggs' => array(
                            'busyTotalSecs' => array('sum' => array('field' => 'secs')),
                            'busyAvgSecs' => array('avg' => array('field' => 'secs')),
                        ),
                    ),
                ),
            ),
        ),
    );

    /** @var array 所有的统计指标 */
    private $statisticItems = array();

    /** @var array 所有需要计算的指标 */
    private $calculateItems = array();

    /**
     * AgentStatisticModel constructor.
     * @param ContainerInterface $container
     */
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
        $hosts = $this->container->getParameter('elasticsearch_hosts');
        $this->client = new Client(array(
            'hosts' => $hosts,
            'logging' => false,
        ));

        /** 如果没有设置置忙原因不按置忙原因查询 */
        $user = $this->container->get("security.token_storage")->getToken()->getUser();
        $vccId = $user->getVccId();

        $conn = $this->container->get('doctrine.dbal.default_connection');
        $reasons = $conn->fetchAll(
            'SELECT id,stat_reason FROM win_agstat_reason WHERE vcc_id=:vcc_id',
            array(':vcc_id' => $vccId)
        );

        if (empty($reasons)) {
            /** @var array 示忙总时长 */
            $this->busyTotalNum = array(
                'filter' => array(
                    'bool' => array(
                        'must' => array(
                            array('term' => array('type' => 11)),
                            array('term' => array('log_type' => 'time')),
                        ),
                    ),
                ),
                'aggs' => array(
                    'ag_groups' => array(
                        'terms' => array('field' => 'ag_id', 'size' => 0),
                        'aggs' => array(
                            'busyTotalSecs' => array('sum' => array('field' => 'secs')),
                            'busyAvgSecs' => array('avg' => array('field' => 'secs')),
                        ),
                    ),
                ),
            );
        }

        $this->statisticItems = array(
            'inboundConnNum' => $this->inboundConnNum,
            'outboundTotalNum' => $this->outboundTotalNum,
            'outboundConnNum' => $this->outboundConnNum,
            'validConnTotalNum' => $this->validConnTotalNum,
            'inboundValidConnTotalNum' => $this->inboundValidConnTotalNum,
            'outboundValidConnTotalNum' => $this->outboundValidConnTotalNum,
            'connTotalNum' => $this->connTotalNum,
            'internalConnNum' => $this->internalConnNum,
            'waitTotalNum' => $this->waitTotalNum,
            'ringTotalNum' => $this->ringTotalNum,
            'consultNum' => $this->consultNum,
            'holdNum' => $this->holdNum,
            'conferenceNum' => $this->conferenceNum,
            'transferTotalNum' => $this->transferTotalNum,
            'transferedConnNum' => $this->transferedConnNum,
            'loginTotalNum' => $this->loginTotalNum,
            'readyTotalSecs' => $this->readyTotalSecs,
            'busyTotalNum' => $this->busyTotalNum,
        );

        //所有需要计算的项
        /*$calculateItems = $this->getcalculateItemAction();
        if (!empty($calculateItems)) {
            $this->calculateItems = array();
            foreach ($calculateItems['agent'] as $key => $val) {
                $val['denominator'] = isset($val['denominator']) ? $val['denominator'] : array();
                $this->calculateItems[$key] = array(
                    'numerator' => array($val['numerator']),
                    'denominator' => array($val['denominator']),
                );
            }
        } else {
            $this->calculateItems = array(
                'workRate' => array(
                    'numerator' => array('inboundConnTotalSecs', 'outboundConnTotalSecs', 'waitTotalSecs'),
                    'denominator' => array('loginTotalSecs'),
                ),
                'busyRate' => array(
                    'numerator' => array('busyTotalSecs'),
                    'denominator' => array('loginTotalSecs'),
                ),
            );
        }*/
    }

    /**
     * 获取坐席天报表统计数据
     *
     * @param array $param 参数，格式为
     *                     array(
     *                         items = array(//统计的字段项
     *                             inboundConnNum,
     *                             inboundConnTotalSecs,
     *                             ...,
     *                         ),
     *                         query = array(//查询条件
     *                             vcc_id => 1,//企业id（必需）
     *                             start_time => 1,//开始时间（必需）
     *                             end_time => 1,//结束时间（必需）
     *                             ag_id => 1,//坐席id，多个坐席id逗号分隔
     *                             que_id => 1,//技能组id，多个技能组id逗号分隔
     *                             group_id => 1,//业务组id，多个业务组id逗号分隔
     *                         )
     *                         options = array(//其他选项
     *                             validSecs => 60,//有效通话时长
     *                         )
     *                     )
     *
     * @return array
     */
    public function getAgentDayStatisticData(array $param)
    {
        if (empty($param)) {
            return array(
                'code' => 401,
                'message' => '统计参数为空',
            );
        }

        if (!is_array($param)) {
            return array(
                'code' => 402,
                'message' => '统计参数格式不为数组',
            );
        }

        if (empty($param['items'])) {
            return array(
                'code' => 403,
                'message' => '统计参数中的字段项items为空',
            );
        }

        if (empty($param['query']['vcc_id'])) {
            return array(
                'code' => 404,
                'message' => '统计参数中的查询项query中缺少企业ID',
            );
        }

        if (empty($param['query']['start_time'])) {
            return array(
                'code' => 405,
                'message' => '统计参数中的查询项query中缺少开始时间start_time',
            );
        }

        if (empty($param['query']['end_time'])) {
            return array(
                'code' => 406,
                'message' => '统计参数中的查询项query中缺少结束时间end_time',
            );
        }

        // 默认配置的计算项
        $this->calculateItems = array(
            'workRate' => array(
                'numerator' => array('inboundConnTotalSecs', 'outboundConnTotalSecs', 'waitTotalSecs'),
                'denominator' => array('loginTotalSecs'),
            ),
            'busyRate' => array(
                'numerator' => array('busyTotalSecs'),
                'denominator' => array('loginTotalSecs'),
            ),
        );

        /** @var array $calculateItems 获取自定义配置的计算项 */
        $roleId = empty($param['role_id']) ? 0 : $param['role_id'];
        $calculateItems = $this->container->get('icsoc_data.model.role')->getcalculateItem($roleId);
        if (!empty($calculateItems)) {
            foreach ($calculateItems['agent'] as $key => $val) {
                $val['numerator'] = isset($val['numerator']) ? $val['numerator'] : array();
                $val['denominator'] = isset($val['denominator']) ? $val['denominator'] : array();
                if (empty($val['denominator']) && empty($val['numerator'])) {
                    continue;
                }
                $this->calculateItems[$key] = array(
                    'numerator' => array($val['numerator']),
                    'denominator' => array($val['denominator']),
                );
            }
        }

        //处理查询条件
        $query = array();
        $vccId = empty($param['query']['vcc_id']) ? 0 : $param['query']['vcc_id'];
        $query[] = array('match' => array('vcc_id' => $vccId));

        $startTime = empty($param['query']['start_time']) ? 0 : $param['query']['start_time'];
        $endTime = empty($param['query']['end_time']) ? 0 : $param['query']['end_time'];
        $query[] = array(
            'range' => array(
                'call_time' => array(
                    'gte' => $startTime,
                    'lte' => $endTime,
                ),
            ),
        );

        $agIds = empty($param['query']['ag_id']) ? 0 : $param['query']['ag_id'];
        if (!empty($agIds)) {
            $agIdArray = explode(',', $agIds);
            $query[] = array(
                'terms' => array(
                    'ag_id' => $agIdArray,
                ),
            );
        }

        $queIds = empty($param['query']['que_id']) ? 0 : $param['query']['que_id'];
        if (!empty($queIds)) {
            $queIdArray = explode(',', $queIds);
            $query[] = array(
                'terms' => array(
                    'que_id' => $queIdArray,
                ),
            );
        }

        $groupIds = empty($param['query']['group_id']) ? 0 : $param['query']['group_id'];
        if (!empty($groupIds)) {
            $groupIdArray = explode(',', $groupIds);
            $query[] = array(
                'terms' => array(
                    'group_id' => $groupIdArray,
                ),
            );
        }

        //处理统计字段项
        $aggsItems = array();
        $items = empty($param['items']) ? array() : $param['items'];
        foreach ($items as $item) {
            if (isset($this->statisticItems[$item])) {
                $aggsItems[$item] = $this->statisticItems[$item];

                //处理有效通话量指标
                if (in_array($item, $this->validItems)) {
                    if (isset($param['options']['validSecs'])) {
                        array_push(
                            $aggsItems[$item]['filter']['bool']['must'],
                            array('range' => array('secs' => array('gte' => $param['options']['validSecs'])))
                        );
                    }
                }
            }
        }

        //获取统计结果
        $params = array(
            'index' => $this->container->getParameter('elasticsearch_index_name'),
            'type' => 'tmp_logs',
            'search_type' => 'count',
            'body' => array(
                'query' => array(
                    'bool' => array(
                        'must' => $query,
                    ),
                ),
                'aggs' => array(
                    //按日期统计所有坐席的统计数据
                    'agg_date' => array(
                        'terms' => array(
                            'field' => 'day',
                            'format' => 'yyyy-MM-dd',
                            'size' => 0,
                        ),
                        'aggs' => $aggsItems,
                    ),
                    //统计所有包含统计数据的坐席
                    'agents' => array(
                        'terms' => array('field' => 'ag_id', 'size' => 0),
                    ),
                ),
            ),
        );
        $result = $this->client->search($params);
        $took = empty($result['took']) ? 0 : $result['took'];

        //获取所有包含数据的坐席
        $agentBuckets = empty($result['aggregations']['agents']['buckets']) ?
            array() : $result['aggregations']['agents']['buckets'];
        $allAgents = array();
        foreach ($agentBuckets as $agentBucket) {
            $key = empty($agentBucket['key']) ? 0 : $agentBucket['key'];
            if (!empty($key)) {
                $allAgents[] = $key;
            }
        }

        /**
         * 解析统计返回的结果，原始数据结构见例子../Resources/doc/AgentDaySample.json
         * 解析完成后的数据结构见例子../Resources/doc/AgentDayResult.json
         */
        $buckets = empty($result['aggregations']['agg_date']['buckets']) ?
            array() : $result['aggregations']['agg_date']['buckets'];

        //释放result占用的内存，防止超过内存限制
        unset($result);

        $parsedResult = array('took' => $took, 'data' => array());
        //记录无法从搜索结果中获取的指标，初始化为所有的指标，获取一项删除一项
        $itemsCanNotGetFromResult = $items;
        /**
         * $buckets为按日期统计的结果，遍历处理各个日期的数据
         */
        foreach ($buckets as $bucket) {
            $statisticDate = empty($bucket['key_as_string']) ? 0 : $bucket['key_as_string'];
            unset($bucket['key']);
            unset($bucket['key_as_string']);
            unset($bucket['doc_count']);

            //初始化所有坐席的所有统计数据指标为0
            foreach ($allAgents as $agentId) {
                foreach ($items as $item) {
                    $parsedResult['data'][$statisticDate][$agentId][$item] = 0;
                }
            }

            /**
             * $bucket为按指标统计的结果，遍历处理各个指标的数据
             */
            foreach ($bucket as $bucketItem => $bucketData) {
                $subBuckets = empty($bucketData['ag_groups']['buckets']) ?
                    array() : $bucketData['ag_groups']['buckets'];

                //将可以从搜索结果中获取的指标从“$itemsCanNotGetFromResult”删除
                if (($searchKey = array_search($bucketItem, $itemsCanNotGetFromResult)) !== false) {
                    unset($itemsCanNotGetFromResult[$searchKey]);
                }

                /**
                 * $subBuckets为按坐席统计的数据，遍历处理各个坐席的统计数据
                 */
                foreach ($subBuckets as $subBucketData) {
                    $agId = empty($subBucketData['key']) ? 0 : $subBucketData['key'];
                    $docCount = empty($subBucketData['doc_count']) ? 0 : $subBucketData['doc_count'];
                    $parsedResult['data'][$statisticDate][$agId][$bucketItem] = $docCount;
                    unset($subBucketData['key']);
                    unset($subBucketData['doc_count']);

                    /**
                     * 处理各个指标下的相关指标的统计数据
                     * 例如呼入接通量相关的统计数据为总呼入接通通话时长、平均呼入接通通话时长
                     *
                     * @var string $subBucketDataItem 相关指标
                     * @var array  $subBucketDataData 相关指标的值，格式为包含键value的数组或包含子统计的数组
                     */
                    foreach ($subBucketData as $subBucketDataItem => $subBucketDataData) {
                        //将可以从搜索结果中获取的指标从“$itemsCanNotGetFromResult”删除
                        if (($searchKey = array_search($bucketItem, $itemsCanNotGetFromResult)) !== false) {
                            unset($itemsCanNotGetFromResult[$searchKey]);
                        }

                        if (in_array($subBucketDataItem, $items)) {
                            /**
                             * 该项为需要统计的项，不包含子统计的数据
                             */
                            $parsedResult['data'][$statisticDate][$agId][$subBucketDataItem] =
                                empty($subBucketDataData['value']) ? 0 : $subBucketDataData['value'];
                        } else {
                            /**
                             * 该项为不需要统计的项，判断是否包含子统计数据，包含则继续处理子统计
                             */
                            if (isset($subBucketDataData['buckets'])) {
                                $childBuckets = empty($subBucketDataData['buckets']) ?
                                    array() : $subBucketDataData['buckets'];
                                $parsedResult['data'][$statisticDate][$agId][$bucketItem] = array();

                                /**
                                 * 继续处理子统计中的项
                                 */
                                foreach ($childBuckets as $childBucket) {
                                    $childKey = !empty($childBucket['key']) || $childBucket['key'] == 0 ?
                                        strval($childBucket['key']) : "0";
                                    $docCount = empty($childBucket['doc_count']) ? 0 : $childBucket['doc_count'];
                                    unset($childBucket['key']);
                                    unset($childBucket['doc_count']);

                                    //如果没有设置示忙原因，则使用原始指标
                                    $parsedResult['data'][$statisticDate][$agId][$bucketItem][$childKey] = $docCount;

                                    /**
                                     * 处理子统计中的相关指标
                                     */
                                    foreach ($childBucket as $cbk => $childBucketData) {
                                        if (!isset($parsedResult['data'][$statisticDate][$agId][$cbk])) {
                                            $parsedResult['data'][$statisticDate][$agId][$cbk] = array();
                                        }
                                        if (!is_array($parsedResult['data'][$statisticDate][$agId][$cbk])) {
                                            $parsedResult['data'][$statisticDate][$agId][$cbk] = array();
                                        }
                                        $parsedResult['data'][$statisticDate][$agId][$cbk][$childKey] =
                                            empty($childBucketData['value']) ? 0 : $childBucketData['value'];
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        //处理需要计算的项，按日期分组
        foreach ($parsedResult['data'] as $dateStatistic => $dateStatisticData) {
            //遍历处理技能组、坐席或企业的数据，按技能组、坐席或企业分组
            foreach ($dateStatisticData as $queStatistic => $queStatisticData) {
                //遍历处理各个指标的数据，按指标分组
                foreach ($queStatisticData as $item => $itemData) {
                    //如果是搜索结果中未统计的项并且是需要计算的项，则执行计算
                    if (in_array($item, $itemsCanNotGetFromResult) && isset($this->calculateItems[$item])) {
                        $calculateRules = empty($this->calculateItems[$item]) ? array() : $this->calculateItems[$item];

                        //未设置计算规则
                        if (empty($calculateRules)) {
                            continue;
                        }

                        $calculItemConfig = isset($calculateItems['agent']) ? $calculateItems['agent'] : array();
                        $numerator = empty($calculateRules['numerator']) ? array() : $calculateRules['numerator'];
                        $denominator = empty($calculateRules['denominator']) ? array() : $calculateRules['denominator'];
                        $numeratorValue = 0;
                        $denominatorValue = 0;

                        //计算分母的值
                        foreach ($denominator as $ruleItem) {
                            if (is_array($ruleItem)) {
                                foreach ($ruleItem as $key => $rules) {
                                    if ($key == 'multiply') {
                                        if (empty($rules['plus'] && empty($rules['minus']))) {
                                            continue;
                                        }
                                        $denominatorValue += $this->container->get('icsoc_custom_report.model.system_statistic')->processMultiplyItems($rules, $queStatisticData, $parsedResult['data'][$dateStatistic][$queStatistic], array_keys($calculItemConfig));
                                    } else {
                                        foreach ($rules as $rule) {
                                            if (!isset($queStatisticData[$rule])) {
                                                if (is_numeric($rule)) {
                                                    $queStatisticData[$rule] = (int) $rule;
                                                    $parsedResult['data'][$dateStatistic][$queStatistic][$rule] = (int) $rule;
                                                } else {
                                                    $queStatisticData[$rule] = 0;
                                                }
                                            }
                                            if (is_array($queStatisticData[$rule])) {
                                                foreach ($queStatisticData[$rule] as $val) {
                                                    $denominatorValue += $val;
                                                }
                                            } else {
                                                $calculItems = array();
                                                $calculItemConfig = isset($calculateItems['agent']) ? $calculateItems['agent'] : array();
                                                foreach ($calculItemConfig as $calculItemK => $calculItemV) {
                                                    $calculItems[] = $calculItemK;
                                                }
                                                if (in_array($rule, $calculItems)) {
                                                    if ($key == 'plus') {
                                                        $denominatorValue += isset($parsedResult['data'][$dateStatistic][$queStatistic][$rule]) ? $parsedResult['data'][$dateStatistic][$queStatistic][$rule] : 0;
                                                    } else {
                                                        $denominatorValue -= isset($parsedResult['data'][$dateStatistic][$queStatistic][$rule]) ? $parsedResult['data'][$dateStatistic][$queStatistic][$rule] : 0;
                                                    }
                                                } else {
                                                    if ($key == 'plus') {
                                                        $denominatorValue += $queStatisticData[$rule];
                                                    } else {
                                                        $denominatorValue -= $queStatisticData[$rule];
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            } else {
                                if (!isset($queStatisticData[$ruleItem])) {
                                    //如果配置项中出现了数字，则为自定义数值的情况，直接用该数字进行运算
                                    if (is_numeric($ruleItem)) {
                                        $queStatisticData[$ruleItem] = (int) $ruleItem;
                                    } else {
                                        $queStatisticData[$ruleItem] = '';
                                    }
                                }
                                $denominatorValue += $queStatisticData[$ruleItem];
                            }
                        }

                        //计算分子的值
                        foreach ($numerator as $ruleItem) {
                            if (is_array($ruleItem)) {
                                foreach ($ruleItem as $key => $rules) {
                                    if ($key == 'multiply') {
                                        if (empty($rules['plus'] && empty($rules['minus']))) {
                                            continue;
                                        }
                                        $numeratorValue += $this->container->get('icsoc_custom_report.model.system_statistic')->processMultiplyItems($rules, $queStatisticData, $parsedResult['data'][$dateStatistic][$queStatistic], array_keys($calculItemConfig));
                                    } else {
                                        foreach ($rules as $rule) {
                                            if (!isset($queStatisticData[$rule])) {
                                                if (is_numeric($rule)) {
                                                    $queStatisticData[$rule] = (int) $rule;
                                                    $parsedResult['data'][$dateStatistic][$queStatistic][$rule] = (int) $rule;
                                                } else {
                                                    $queStatisticData[$rule] = 0;
                                                }
                                            }
                                            $ruleItemValue = 0;
                                            if (is_array($queStatisticData[$rule])) {
                                                foreach ($queStatisticData[$rule] as $val) {
                                                    $ruleItemValue = isset($queStatisticData[$val]) ? $queStatisticData[$val] : 0;
                                                }
                                            } else {
                                                $ruleItemValue = isset($queStatisticData[$rule]) ? $queStatisticData[$rule] : 0;
                                            }
                                            if (is_array($ruleItemValue)) {
                                                $numeratorValue = array();
                                                //需要计算的值为一个数组，如X秒接通量、接通率
                                                foreach ($ruleItemValue as $key => $value) {
                                                    if (isset($numeratorValue[$key])) {
                                                        $numeratorValue[$key] += isset($ruleItemValue[$key]) ? $ruleItemValue[$key] : 0;
                                                    } else {
                                                        $numeratorValue[$key] = isset($ruleItemValue[$key]) ? $ruleItemValue[$key] : 0;
                                                    }
                                                }
                                            } else {
                                                if (is_array($queStatisticData[$rule])) {
                                                    foreach ($queStatisticData[$rule] as $val) {
                                                        $numeratorValue += $val;
                                                    }
                                                } else {
                                                    $calculItems = array();
                                                    $calculItemConfig = isset($calculateItems['agent']) ? $calculateItems['agent'] : array();
                                                    foreach ($calculItemConfig as $calculItemK => $calculItemV) {
                                                        $calculItems[] = $calculItemK;
                                                    }
                                                    if (in_array($rule, $calculItems)) {
                                                        if ($key == 'plus') {
                                                            $numeratorValue += isset($parsedResult['data'][$dateStatistic][$queStatistic][$rule]) ? $parsedResult['data'][$dateStatistic][$queStatistic][$rule] : 0;
                                                        } else {
                                                            $numeratorValue -= isset($parsedResult['data'][$dateStatistic][$queStatistic][$rule]) ? $parsedResult['data'][$dateStatistic][$queStatistic][$rule] : 0;
                                                        }
                                                    } else {
                                                        if ($key == 'plus') {
                                                            $numeratorValue += $queStatisticData[$rule];
                                                        } else {
                                                            $numeratorValue -= $queStatisticData[$rule];
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            } else {
                                $ruleItemValue = isset($queStatisticData[$ruleItem]) ? $queStatisticData[$ruleItem] : is_numeric($ruleItem) ? (int) $ruleItem : 0;
                                if (is_array($ruleItemValue)) {
                                    $numeratorValue = array();
                                    //需要计算的值为一个数组，如X秒接通量、接通率
                                    foreach ($ruleItemValue as $key => $value) {
                                        if (isset($numeratorValue[$key])) {
                                            $numeratorValue[$key] += isset($ruleItemValue[$key]) ? $ruleItemValue[$key] : 0;
                                        } else {
                                            $numeratorValue[$key] = isset($ruleItemValue[$key]) ? $ruleItemValue[$key] : 0;
                                        }
                                    }
                                } else {
                                    //需要计算的值为单个值
                                    if (!isset($queStatisticData[$ruleItem])) {
                                        if (is_numeric($ruleItem)) {
                                            $queStatisticData[$ruleItem] = (int) $ruleItem;
                                        } else {
                                            $queStatisticData[$ruleItem] = 0;
                                        }
                                    }
                                    $numeratorValue += $queStatisticData[$ruleItem];
                                }
                            }
                        }

                        //计算统计项的值
                        if (isset($calculateItems['agent'][$item])) {
                            if (empty($calculateItems['agent'][$item]['percent'])) {
                                if (is_array($numeratorValue)) {
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item] = array();
                                    foreach ($numeratorValue as $key => $value) {
                                        $parsedResult['data'][$dateStatistic][$queStatistic][$item][$key] =
                                            $denominatorValue == 0 ?
                                                $numeratorValue[$key] : (round($numeratorValue[$key] / $denominatorValue, 1));
                                    }
                                } else {
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item] = $denominatorValue == 0 ?
                                        $numeratorValue : (round($numeratorValue / $denominatorValue, 1));
                                }
                            } else {
                                if (is_array($numeratorValue)) {
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item] = array();
                                    foreach ($numeratorValue as $key => $value) {
                                        if ($denominatorValue == 0) {
                                            $resultValue = 0;
                                        } else {
                                            if (($numeratorValue[$key] / $denominatorValue) > 1) {
                                                $resultValue = 1;
                                            } else {
                                                $resultValue = ($numeratorValue[$key] / $denominatorValue);
                                            }
                                        }
                                        $parsedResult['data'][$dateStatistic][$queStatistic][$item][$key] =
                                            $denominatorValue == 0 ?
                                                '0%' : (round($resultValue, 4) * 100).'%';
                                    }
                                } else {
                                    if ($denominatorValue == 0) {
                                        $resultValue = 0;
                                    } else {
                                        if (($numeratorValue / $denominatorValue) > 1) {
                                            $resultValue = 1;
                                        } else {
                                            $resultValue = ($numeratorValue / $denominatorValue);
                                        }
                                    }
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item] = $denominatorValue == 0 ?
                                        '0%' : (round($resultValue, 4) * 100).'%';
                                }
                            }
                        } else {
                            if (is_array($numeratorValue)) {
                                $parsedResult['data'][$dateStatistic][$queStatistic][$item] = array();
                                foreach ($numeratorValue as $key => $value) {
                                    if ($denominatorValue == 0) {
                                        $resultValue = 0;
                                    } else {
                                        if (($numeratorValue[$key] / $denominatorValue) > 1) {
                                            $resultValue = 1;
                                        } else {
                                            $resultValue = ($numeratorValue[$key] / $denominatorValue);
                                        }
                                    }
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item][$key] =
                                        $denominatorValue == 0 ?
                                            '0%' : (round($resultValue, 4) * 100).'%';
                                }
                            } else {
                                if ($denominatorValue == 0) {
                                    $resultValue = 0;
                                } else {
                                    if (($numeratorValue / $denominatorValue) > 1) {
                                        $resultValue = 1;
                                    } else {
                                        $resultValue = ($numeratorValue / $denominatorValue);
                                    }
                                }
                                $parsedResult['data'][$dateStatistic][$queStatistic][$item] = $denominatorValue == 0 ?
                                    '0%' : (round($resultValue, 4) * 100).'%';
                            }
                        }
                    }

                    //处理浮点数的格式
                    if (is_float($itemData)) {
                        $parsedResult['data'][$dateStatistic][$queStatistic][$item] = round($itemData, 1);
                    } elseif (is_array($itemData)) {
                        foreach ($itemData as $subItem => $data) {
                            if (is_float($data)) {
                                $parsedResult['data'][$dateStatistic][$queStatistic][$item][$subItem] = round($data, 1);
                            }
                        }
                    }
                }
            }
        }

        return $parsedResult;
    }

    /**
     * 获取坐席月报表统计数据
     *
     * @param array $param 参数，格式为
     *                     array(
     *                         items = array(//统计的字段项
     *                             inboundConnNum,
     *                             inboundConnTotalSecs,
     *                             ...,
     *                         ),
     *                         query = array(//查询条件
     *                             vcc_id => 1,//企业id（必需）
     *                             start_time => 1,//开始时间（必需）
     *                             end_time => 1,//结束时间（必需）
     *                             ag_id => 1,//坐席id，多个坐席id逗号分隔
     *                             que_id => 1,//技能组id，多个技能组id逗号分隔
     *                             group_id => 1,//业务组id，多个业务组id逗号分隔
     *                         )
     *                     )
     *
     * @return array
     */
    public function getAgentMonthStatisticData(array $param)
    {
        if (empty($param)) {
            return array(
                'code' => 401,
                'message' => '统计参数为空',
            );
        }

        if (!is_array($param)) {
            return array(
                'code' => 402,
                'message' => '统计参数格式不为数组',
            );
        }

        if (empty($param['items'])) {
            return array(
                'code' => 403,
                'message' => '统计参数中的字段项items为空',
            );
        }

        if (empty($param['query']['vcc_id'])) {
            return array(
                'code' => 404,
                'message' => '统计参数中的查询项query中缺少企业ID',
            );
        }

        if (empty($param['query']['start_time'])) {
            return array(
                'code' => 405,
                'message' => '统计参数中的查询项query中缺少开始时间start_time',
            );
        }

        if (empty($param['query']['end_time'])) {
            return array(
                'code' => 406,
                'message' => '统计参数中的查询项query中缺少结束时间end_time',
            );
        }

        // 默认配置的计算项
        $this->calculateItems = array(
            'workRate' => array(
                'numerator' => array('inboundConnTotalSecs', 'outboundConnTotalSecs', 'waitTotalSecs'),
                'denominator' => array('loginTotalSecs'),
            ),
            'busyRate' => array(
                'numerator' => array('busyTotalSecs'),
                'denominator' => array('loginTotalSecs'),
            ),
        );

        /** @var array $calculateItems 获取自定义配置的计算项 */
        $roleId = empty($param['role_id']) ? 0 : $param['role_id'];
        $calculateItems = $this->container->get('icsoc_data.model.role')->getcalculateItem($roleId);
        if (!empty($calculateItems)) {
            foreach ($calculateItems['agent'] as $key => $val) {
                $val['denominator'] = isset($val['denominator']) ? $val['denominator'] : array();
                $this->calculateItems[$key] = array(
                    'numerator' => array($val['numerator']),
                    'denominator' => array($val['denominator']),
                );
            }
        }

        //处理查询条件
        $query = array();
        $vccId = empty($param['query']['vcc_id']) ? 0 : $param['query']['vcc_id'];
        $query[] = array('match' => array('vcc_id' => $vccId));

        $startTime = empty($param['query']['start_time']) ? 0 : $param['query']['start_time'];
        $endTime = empty($param['query']['end_time']) ? 0 : $param['query']['end_time'];
        $query[] = array(
            'range' => array(
                'call_time' => array(
                    'gte' => $startTime,
                    'lte' => $endTime,
                ),
            ),
        );

        $agIds = empty($param['query']['ag_id']) ? 0 : $param['query']['ag_id'];
        if (!empty($agIds)) {
            $agIdArray = explode(',', $agIds);
            $query[] = array(
                'terms' => array(
                    'ag_id' => $agIdArray,
                ),
            );
        }

        $queIds = empty($param['query']['que_id']) ? 0 : $param['query']['que_id'];
        if (!empty($queIds)) {
            $queIdArray = explode(',', $queIds);
            $query[] = array(
                'terms' => array(
                    'que_id' => $queIdArray,
                ),
            );
        }

        $groupIds = empty($param['query']['group_id']) ? 0 : $param['query']['group_id'];
        if (!empty($groupIds)) {
            $groupIdArray = explode(',', $groupIds);
            $query[] = array(
                'terms' => array(
                    'group_id' => $groupIdArray,
                ),
            );
        }

        //处理统计字段项
        $aggsItems = array();
        $items = empty($param['items']) ? array() : $param['items'];
        foreach ($items as $item) {
            if (isset($this->statisticItems[$item])) {
                $aggsItems[$item] = $this->statisticItems[$item];

                //处理有效通话量指标
                if (in_array($item, $this->validItems)) {
                    if (isset($param['options']['validSecs'])) {
                        array_push(
                            $aggsItems[$item]['filter']['bool']['must'],
                            array('range' => array('secs' => array('gte' => $param['options']['validSecs'])))
                        );
                    }
                }
            }
        }

        //获取统计结果
        $params = array(
            'index' => $this->container->getParameter('elasticsearch_index_name'),
            'type' => 'tmp_logs',
            'search_type' => 'count',
            'body' => array(
                'query' => array(
                    'bool' => array(
                        'must' => $query,
                    ),
                ),
                'aggs' => array(
                    //按日期统计所有坐席的统计数据
                    'agg_date' => array(
                        'terms' => array(
                            'field' => 'month',
                            'format' => 'yyyy-MM',
                            'size' => 0,
                        ),
                        'aggs' => $aggsItems,
                    ),
                    //统计所有包含统计数据的坐席
                    'agents' => array(
                        'terms' => array('field' => 'ag_id', 'size' => 0),
                    ),
                ),
            ),
        );
        $result = $this->client->search($params);
        $took = empty($result['took']) ? 0 : $result['took'];

        //获取所有包含数据的坐席
        $agentBuckets = empty($result['aggregations']['agents']['buckets']) ?
            array() : $result['aggregations']['agents']['buckets'];
        $allAgents = array();
        foreach ($agentBuckets as $agentBucket) {
            $key = empty($agentBucket['key']) ? 0 : $agentBucket['key'];
            if (!empty($key)) {
                $allAgents[] = $key;
            }
        }

        /**
         * 解析统计返回的结果，原始数据结构见例子../Resources/doc/AgentDaySample.json
         * 解析完成后的数据结构见例子../Resources/doc/AgentDayResult.json
         */
        $buckets = empty($result['aggregations']['agg_date']['buckets']) ?
            array() : $result['aggregations']['agg_date']['buckets'];

        //释放result占用的内存，防止超过内存限制
        unset($result);

        $parsedResult = array('took' => $took, 'data' => array());
        //记录无法从搜索结果中获取的指标，初始化为所有的指标，获取一项删除一项
        $itemsCanNotGetFromResult = $items;
        /**
         * $buckets为按日期统计的结果，遍历处理各个日期的数据
         */
        foreach ($buckets as $bucket) {
            $statisticDate = empty($bucket['key_as_string']) ? 0 : $bucket['key_as_string'];
            unset($bucket['key']);
            unset($bucket['key_as_string']);
            unset($bucket['doc_count']);

            //初始化所有坐席的所有统计数据指标为0
            foreach ($allAgents as $agentId) {
                foreach ($items as $item) {
                    $parsedResult['data'][$statisticDate][$agentId][$item] = 0;
                }
            }

            /**
             * $bucket为按指标统计的结果，遍历处理各个指标的数据
             */
            foreach ($bucket as $bucketItem => $bucketData) {
                $subBuckets = empty($bucketData['ag_groups']['buckets']) ?
                    array() : $bucketData['ag_groups']['buckets'];

                //将可以从搜索结果中获取的指标从“$itemsCanNotGetFromResult”删除
                if (($searchKey = array_search($bucketItem, $itemsCanNotGetFromResult)) !== false) {
                    unset($itemsCanNotGetFromResult[$searchKey]);
                }

                /**
                 * $subBuckets为按坐席统计的数据，遍历处理各个坐席的统计数据
                 */
                foreach ($subBuckets as $subBucketData) {
                    $agId = empty($subBucketData['key']) ? 0 : $subBucketData['key'];
                    $docCount = empty($subBucketData['doc_count']) ? 0 : $subBucketData['doc_count'];
                    $parsedResult['data'][$statisticDate][$agId][$bucketItem] = $docCount;
                    unset($subBucketData['key']);
                    unset($subBucketData['doc_count']);

                    /**
                     * 处理各个指标下的相关指标的统计数据
                     * 例如呼入接通量相关的统计数据为总呼入接通通话时长、平均呼入接通通话时长
                     *
                     * @var string $subBucketDataItem 相关指标
                     * @var array  $subBucketDataData 相关指标的值，格式为包含键value的数组或包含子统计的数组
                     */
                    foreach ($subBucketData as $subBucketDataItem => $subBucketDataData) {
                        //将可以从搜索结果中获取的指标从“$itemsCanNotGetFromResult”删除
                        if (($searchKey = array_search($bucketItem, $itemsCanNotGetFromResult)) !== false) {
                            unset($itemsCanNotGetFromResult[$searchKey]);
                        }

                        if (in_array($subBucketDataItem, $items)) {
                            /**
                             * 该项为需要统计的项，不包含子统计的数据
                             */
                            $parsedResult['data'][$statisticDate][$agId][$subBucketDataItem] =
                                empty($subBucketDataData['value']) ? 0 : $subBucketDataData['value'];
                        } else {
                            /**
                             * 该项为不需要统计的项，判断是否包含子统计数据，包含则继续处理子统计
                             */
                            if (isset($subBucketDataData['buckets'])) {
                                $childBuckets = empty($subBucketDataData['buckets']) ?
                                    array() : $subBucketDataData['buckets'];
                                $parsedResult['data'][$statisticDate][$agId][$bucketItem] = array();

                                /**
                                 * 继续处理子统计中的项
                                 */
                                foreach ($childBuckets as $childBucket) {
                                    $childKey = !empty($childBucket['key']) || $childBucket['key'] == 0 ?
                                        strval($childBucket['key']) : "0";
                                    $docCount = empty($childBucket['doc_count']) ? 0 : $childBucket['doc_count'];
                                    unset($childBucket['key']);
                                    unset($childBucket['doc_count']);

                                    //如果没有设置示忙原因，则使用原始指标
                                    $parsedResult['data'][$statisticDate][$agId][$bucketItem][$childKey] = $docCount;

                                    /**
                                     * 处理子统计中的相关指标
                                     */
                                    foreach ($childBucket as $cbk => $childBucketData) {
                                        if (!isset($parsedResult['data'][$statisticDate][$agId][$cbk])) {
                                            $parsedResult['data'][$statisticDate][$agId][$cbk] = array();
                                        }
                                        if (!is_array($parsedResult['data'][$statisticDate][$agId][$cbk])) {
                                            $parsedResult['data'][$statisticDate][$agId][$cbk] = array();
                                        }
                                        $parsedResult['data'][$statisticDate][$agId][$cbk][$childKey] =
                                            empty($childBucketData['value']) ? 0 : $childBucketData['value'];
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        //处理需要计算的项，按日期分组
        foreach ($parsedResult['data'] as $dateStatistic => $dateStatisticData) {
            //遍历处理技能组、坐席或企业的数据，按技能组、坐席或企业分组
            foreach ($dateStatisticData as $queStatistic => $queStatisticData) {
                //遍历处理各个指标的数据，按指标分组
                foreach ($queStatisticData as $item => $itemData) {
                    //如果是搜索结果中未统计的项并且是需要计算的项，则执行计算
                    if (in_array($item, $itemsCanNotGetFromResult) && isset($this->calculateItems[$item])) {
                        $calculateRules = empty($this->calculateItems[$item]) ? array() : $this->calculateItems[$item];

                        //未设置计算规则
                        if (empty($calculateRules)) {
                            continue;
                        }

                        $calculItemConfig = isset($calculateItems['agent']) ? $calculateItems['agent'] : array();
                        $numerator = empty($calculateRules['numerator']) ? array() : $calculateRules['numerator'];
                        $denominator = empty($calculateRules['denominator']) ? array() : $calculateRules['denominator'];
                        $numeratorValue = 0;
                        $denominatorValue = 0;

                        //计算分母的值
                        foreach ($denominator as $ruleItem) {
                            if (is_array($ruleItem)) {
                                foreach ($ruleItem as $key => $rules) {
                                    if ($key == 'multiply') {
                                        if (empty($rules['plus'] && empty($rules['minus']))) {
                                            continue;
                                        }
                                        $denominatorValue += $this->container->get('icsoc_custom_report.model.system_statistic')->processMultiplyItems($rules, $queStatisticData, $parsedResult['data'][$dateStatistic][$queStatistic], array_keys($calculItemConfig));
                                    } else {
                                        foreach ($rules as $rule) {
                                            if (!isset($queStatisticData[$rule])) {
                                                //如果配置项中出现了数字，则为自定义数值的情况，直接用该数字进行运算
                                                if (is_numeric($rule)) {
                                                    $queStatisticData[$rule] = (int) $rule;
                                                    $parsedResult['data'][$dateStatistic][$queStatistic][$rule] = (int) $rule;
                                                } else {
                                                    $queStatisticData[$rule] = 0;
                                                }
                                            }
                                            if (is_array($queStatisticData[$rule])) {
                                                foreach ($queStatisticData[$rule] as $val) {
                                                    $denominatorValue += $val;
                                                }
                                            } else {
                                                $calculItems = array();
                                                $calculItemConfig = isset($calculateItems['agent']) ? $calculateItems['agent'] : array();
                                                foreach ($calculItemConfig as $calculItemK => $calculItemV) {
                                                    $calculItems[] = $calculItemK;
                                                }
                                                if (in_array($rule, $calculItems)) {
                                                    if ($key == 'plus') {
                                                        $denominatorValue += isset($parsedResult['data'][$dateStatistic][$queStatistic][$rule]) ? $parsedResult['data'][$dateStatistic][$queStatistic][$rule] : 0;
                                                    } else {
                                                        $denominatorValue -= isset($parsedResult['data'][$dateStatistic][$queStatistic][$rule]) ? $parsedResult['data'][$dateStatistic][$queStatistic][$rule] : 0;
                                                    }
                                                } else {
                                                    if ($key == 'plus') {
                                                        $denominatorValue += $queStatisticData[$rule];
                                                    } else {
                                                        $denominatorValue -= $queStatisticData[$rule];
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            } else {
                                if (!isset($queStatisticData[$ruleItem])) {
                                    if (is_numeric($ruleItem)) {
                                        $queStatisticData[$ruleItem] = (int) $ruleItem;
                                    } else {
                                        $queStatisticData[$ruleItem] = 0;
                                    }
                                }
                                $denominatorValue += $queStatisticData[$ruleItem];
                            }

                        }

                        //计算分子的值
                        foreach ($numerator as $ruleItem) {
                            if (is_array($ruleItem)) {
                                foreach ($ruleItem as $key => $rules) {
                                    if ($key == 'multiply') {
                                        if (empty($rules['plus'] && empty($rules['minus']))) {
                                            continue;
                                        }
                                        $numeratorValue += $this->container->get('icsoc_custom_report.model.system_statistic')->processMultiplyItems($rules, $queStatisticData, $parsedResult['data'][$dateStatistic][$queStatistic], array_keys($calculItemConfig));
                                    } else {
                                        foreach ($rules as $rule) {
                                            if (!isset($queStatisticData[$rule])) {
                                                if (is_numeric($rule)) {
                                                    $queStatisticData[$rule] = (int) $rule;
                                                    $parsedResult['data'][$dateStatistic][$queStatistic][$rule] = (int) $rule;
                                                } else {
                                                    $queStatisticData[$rule] = 0;
                                                }
                                            }
                                            $ruleItemValue = 0;
                                            if (is_array($queStatisticData[$rule])) {
                                                foreach ($queStatisticData[$rule] as $val) {
                                                    $ruleItemValue = isset($queStatisticData[$val]) ? $queStatisticData[$val] : 0;
                                                }
                                            } else {
                                                $ruleItemValue = isset($queStatisticData[$rule]) ? $queStatisticData[$rule] : 0;
                                            }
                                            if (is_array($ruleItemValue)) {
                                                $numeratorValue = array();
                                                //需要计算的值为一个数组，如X秒接通量、接通率
                                                foreach ($ruleItemValue as $key => $value) {
                                                    if (isset($numeratorValue[$key])) {
                                                        $numeratorValue[$key] += isset($ruleItemValue[$key]) ? $ruleItemValue[$key] : 0;
                                                    } else {
                                                        $numeratorValue[$key] = isset($ruleItemValue[$key]) ? $ruleItemValue[$key] : 0;
                                                    }
                                                }
                                            } else {
                                                if (is_array($queStatisticData[$rule])) {
                                                    foreach ($queStatisticData[$rule] as $val) {
                                                        $numeratorValue += $val;
                                                    }
                                                } else {
                                                    $calculItems = array();
                                                    $calculItemConfig = isset($calculateItems['agent']) ? $calculateItems['agent'] : array();
                                                    foreach ($calculItemConfig as $calculItemK => $calculItemV) {
                                                        $calculItems[] = $calculItemK;
                                                    }
                                                    if (in_array($rule, $calculItems)) {
                                                        if ($key == 'plus') {
                                                            $numeratorValue += isset($parsedResult['data'][$dateStatistic][$queStatistic][$rule]) ? $parsedResult['data'][$dateStatistic][$queStatistic][$rule] : 0;
                                                        } else {
                                                            $numeratorValue -= isset($parsedResult['data'][$dateStatistic][$queStatistic][$rule]) ? $parsedResult['data'][$dateStatistic][$queStatistic][$rule] : 0;
                                                        }
                                                    } else {
                                                        if ($key == 'plus') {
                                                            $numeratorValue += $queStatisticData[$rule];
                                                        } else {
                                                            $numeratorValue -= $queStatisticData[$rule];
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            } else {
                                $ruleItemValue = isset($queStatisticData[$ruleItem]) ? $queStatisticData[$ruleItem] : is_numeric($ruleItem) ? (int) $ruleItem : 0;
                                if (is_array($ruleItemValue)) {
                                    $numeratorValue = array();
                                    //需要计算的值为一个数组，如X秒接通量、接通率
                                    foreach ($ruleItemValue as $key => $value) {
                                        if (isset($numeratorValue[$key])) {
                                            $numeratorValue[$key] += isset($ruleItemValue[$key]) ? $ruleItemValue[$key] : 0;
                                        } else {
                                            $numeratorValue[$key] = isset($ruleItemValue[$key]) ? $ruleItemValue[$key] : 0;
                                        }
                                    }
                                } else {
                                    //需要计算的值为单个值
                                    if (!isset($queStatisticData[$ruleItem])) {
                                        if (is_numeric($ruleItem)) {
                                            $queStatisticData[$ruleItem] = (int) $ruleItem;
                                        } else {
                                            $queStatisticData[$ruleItem] = 0;
                                        }
                                    }
                                    $numeratorValue += $queStatisticData[$ruleItem];
                                }
                            }
                        }

                        //计算统计项的值
                        if (isset($calculateItems['agent'][$item])) {
                            if (empty($calculateItems['agent'][$item]['percent'])) {
                                if (is_array($numeratorValue)) {
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item] = array();
                                    foreach ($numeratorValue as $key => $value) {
                                        $parsedResult['data'][$dateStatistic][$queStatistic][$item][$key] =
                                            $denominatorValue == 0 ?
                                                $numeratorValue[$key] : (round($numeratorValue[$key] / $denominatorValue, 1));
                                    }
                                } else {
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item] = $denominatorValue == 0 ?
                                        $numeratorValue : (round($numeratorValue / $denominatorValue, 1));
                                }
                            } else {
                                if (is_array($numeratorValue)) {
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item] = array();
                                    foreach ($numeratorValue as $key => $value) {
                                        if ($denominatorValue == 0) {
                                            $resultValue = 0;
                                        } else {
                                            if (($numeratorValue[$key] / $denominatorValue) > 1) {
                                                $resultValue = 1;
                                            } else {
                                                $resultValue = ($numeratorValue[$key] / $denominatorValue);
                                            }
                                        }
                                        $parsedResult['data'][$dateStatistic][$queStatistic][$item][$key] =
                                            $denominatorValue == 0 ?
                                                '0%' : (round($resultValue, 4) * 100).'%';
                                    }
                                } else {
                                    if ($denominatorValue == 0) {
                                        $resultValue = 0;
                                    } else {
                                        if (($numeratorValue / $denominatorValue) > 1) {
                                            $resultValue = 1;
                                        } else {
                                            $resultValue = ($numeratorValue / $denominatorValue);
                                        }
                                    }
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item] = $denominatorValue == 0 ?
                                        '0%' : (round($resultValue, 4) * 100).'%';
                                }
                            }
                        } else {
                            if (is_array($numeratorValue)) {
                                $parsedResult['data'][$dateStatistic][$queStatistic][$item] = array();
                                foreach ($numeratorValue as $key => $value) {
                                    if ($denominatorValue == 0) {
                                        $resultValue = 0;
                                    } else {
                                        if (($numeratorValue[$key] / $denominatorValue) > 1) {
                                            $resultValue = 1;
                                        } else {
                                            $resultValue = ($numeratorValue[$key] / $denominatorValue);
                                        }
                                    }
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item][$key] =
                                        $denominatorValue == 0 ?
                                            '0%' : (round($resultValue, 4) * 100).'%';
                                }
                            } else {
                                if ($denominatorValue == 0) {
                                    $resultValue = 0;
                                } else {
                                    if (($numeratorValue / $denominatorValue) > 1) {
                                        $resultValue = 1;
                                    } else {
                                        $resultValue = ($numeratorValue / $denominatorValue);
                                    }
                                }
                                $parsedResult['data'][$dateStatistic][$queStatistic][$item] = $denominatorValue == 0 ?
                                    '0%' : (round($resultValue, 4) * 100).'%';
                            }
                        }
                    }

                    //处理浮点数的格式
                    if (is_float($itemData)) {
                        $parsedResult['data'][$dateStatistic][$queStatistic][$item] = round($itemData, 1);
                    } elseif (is_array($itemData)) {
                        foreach ($itemData as $subItem => $data) {
                            if (is_float($data)) {
                                $parsedResult['data'][$dateStatistic][$queStatistic][$item][$subItem] = round($data, 1);
                            }
                        }
                    }
                }
            }
        }

        return $parsedResult;
    }
}
